<html>
<head>
<script type="text/javascript" src="db.js"></script>
<script type="text/javascript" src="prefs.js"></script>
<script type="text/javascript" src="tools.js"></script>
<script type="text/javascript" src="fetchers.js"></script>
<script>

/*
Maps the tab id to a structure containing currently loaded url and some info about it.
*/
var tabMap = {};
var enabled = true;
var specbadge = false;

function storeRank(fetcher, data, url, val) {
  if (null==val) {
    return ;
  }
  SeoprofesionalDb.add_rank(url, fetcher.id, val);
  data.ranks[fetcher.id] = val;

  chrome.tabs.getSelected(null, function(tab) {
    if (tab.id==data.tabId) {
      tabSelected(tab);
    }
  });
}

function fetchRank(data, ff) {
  SeoprofesionalDb.get_rank(ff.updateUri(data.url), ff.id, function(dt, val) {
    var refetch = false;
    if (null==dt) {
      refetch = true;
    } else {
      var d = dt;
      var now = new Date();
      d.setDate(d.getDate()+ff.refresh);
      if (d<now) {
        refetch = true;
      }
    }
    if (null!=val) {
      data.ranks[ff.id] = val;
    }
    if (refetch) {
      ff.fetch(function(ff, url, val) {
        if (null!=val) {
          storeRank(ff, data, url, val);
        }
        if ("refreshedCallback" in data) {
          data.refreshedCallback();
        }
      }, data.url);
    }
    if ("tabId" in data) {
      chrome.tabs.getSelected(null, function(tab) {
        if (tab.id==data.tabId) {
          tabSelected(tab);
        }
      });
    }
  });
}

function initFetch(data) {
  for (var i = 0;i<SeoprofesionalFetchers.length;i++) {
    var f = SeoprofesionalFetchers[i];
    if (f.enabled) {
      fetchRank(data, f);
    }
  }
}

function isRankable(url) {
  return "http://"==url.substr(0, 7) || "https://"==url.substr(0, 8);
}
function updateTab(tabId) {
  chrome.tabs.get(tabId, function(tab) {
    var changed = false;
    if (!(tabId in tabMap)) {
      tabMap[tabId] = { "url": null, "rankable": false, tabId: tabId };
      changed = true;
    }
    if ("url" in tab) {
      var data = tabMap[tabId];
      if (data.url!=tab.url) {
        changed = true;
        data = {
          "tabId": tabId,
          "url": tab.url,
          "rankable": isRankable(tab.url),
          "ranks": {}
        }
        tabMap[tabId] = data;
        if (data.rankable) {
          // possibly invoke rank re-fetch
          if (enabled) {
            initFetch(data);
          }
        }
      }
    }
    if (changed && tab.selected) {
      tabSelected(tab);
    }
  });
}
function tabSelected(tab) {
  if (!enabled) {
    chrome.browserAction.setIcon({path: "d.png"});
    chrome.browserAction.setTitle({title: chrome.i18n.getMessage("disabled")})
    chrome.browserAction.setBadgeText({text:""});
    return ;
  }
  if (!(tab.id in tabMap)) {
    tabMap[tab.id] = { "url": null, "rankable": false, "tabId": tab.id };
  }
  var data = tabMap[tab.id];
  if (data.url && data.url!=tab.url) {
    console.log("URL differs for the tab:", data, tab);
  }
  if (data.rankable) {
    chrome.browserAction.setIcon({path: "e.png"});
    var title = "";
    var badge = "";
    var pagerank = null;
    var srank = null;
    var color = null;
    for (var i = 0;i<SeoprofesionalFetchers.length;i++) {
      var f = SeoprofesionalFetchers[i];
      if (f.id in data.ranks) {
        if("pagerank"==f.name)  pagerank = data.ranks[f.id];
        else if("srank"==f.name)  srank = data.ranks[f.id];
        if(""!=title) title+= "\n";
        title+= f.nicename + ": " + data.ranks[f.id]

        if (""==badge || f.prefered) {
          badge = "" + data.ranks[f.id];
          color = f.color_array;
        }
      }
    }
    if (specbadge) {
      if (null==pagerank) pagerank = "-";
      if (null==srank) srank = "-";
      badge = "" + pagerank + "|" + srank;
    } else {
      badge = SeoprofesionalTools.suffixize(badge);
    }
    chrome.browserAction.setTitle({title:title});
    chrome.browserAction.setBadgeText({text:badge});
    if (null!=color) {
      chrome.browserAction.setBadgeBackgroundColor({color: color});
    }
  } else {
    chrome.browserAction.setIcon({path: "u.png"});
    chrome.browserAction.setTitle({title: chrome.i18n.getMessage("unavailable")})
    chrome.browserAction.setBadgeText({text:""});
  }
}

chrome.tabs.onUpdated.addListener(updateTab);
chrome.tabs.onCreated.addListener(function(tab) {
  updateTab(tab.id);
});

chrome.tabs.onSelectionChanged.addListener(function(tabId, changeInfo) {
  chrome.tabs.get(tabId, function(tab) {
    tabSelected(tab);
  });
});
chrome.tabs.onRemoved.addListener(function(tabId) {
  delete tabMap[tabId];
});

function onStorage(evt) {
  if ("options.enabled"==evt.key) {
    enabled = prefsGetBool("enabled", true);
  }
  if ("options.specbadge"==evt.key) {
    specbadge = prefsGetBool("specbadge", false);
  }
};

function init() {
  chrome.browserAction.setIcon({path: "d.png"});
  window.addEventListener("storage", onStorage, false);
  enabled = prefsGetBool("enabled", true);
  specbadge = prefsGetBool("specbadge", false);
}

/**
 * Posts details about given url to a port.
 */
function postUrlDetails(port, url, data) {
    if (!isRankable(url)) {
        port.postMessage({
            type: "status",
            info: "unavailable"
        });
        return ;
    }
    port.postMessage({
        type: "url",
        url: url,
        data: data
    });
    SeoprofesionalDb.is_whitelisted(url, function(res) {
        port.postMessage({
            type: "whitelist",
            value: res
        });
        // load the data and send them over only if we are whitelisted
        if (res) {
            for (var i = 0;i<SeoprofesionalFetchers.length;i++) {
                var f = SeoprofesionalFetchers[i];
                if (f.enabled) {
                    sendDataset(port, f.updateUri(url), f);
                }
            }
        }
    });
}

chrome.extension.onConnect.addListener(function(port) {
  if ("seoppopup"==port.name) {
    port.onMessage.addListener(function(param) {
      if ("toggle"==param.type) {
        enabled = !enabled;
        prefsSet("enabled", enabled);
        chrome.tabs.getSelected(null, function(tab) { tabSelected(tab); });
      } else if ("whitelist"==param.type) {
        SeoprofesionalDb.whitelist(param.url);
      } else if ("unwhitelist"==param.type) {
        SeoprofesionalDb.un_whitelist(param.url);
      } else if ("current"==param.type) {
        port.postMessage({
          type: "status",
          info: enabled ? "enabled" : "disabled"
        });
        chrome.tabs.getSelected(null, function(tab) {
          postUrlDetails(port, tab.url, tabMap[tab.id].ranks);
        });
      } else if ("get"==param.type) {
          postUrlDetails(port, param.url, null);
      }
    });
  } else if ("seoputility"==port.name) {
    port.onMessage.addListener(function(param) {
      if ("reloadurl"==param.type) {
        fetchRankAndTellUtility(port, param.url);
      } else if ("reloaddomain"==param.type) {
        SeoprofesionalDb.get_sub(param.url, function(kids) {
          for (var i = 0;i<kids.length;i++) {
            // FIXME: this is not very smart as it may send MANY requests at the same
            // time. I am afraid the current infrastructure does not allow for much more.
            // Anyhow, chrome surely has got some kind of internal resource management
            // so it won't become choked by this.
            fetchRankAndTellUtility(port, kids[i]);
          }
        });
      }
    });
  }
});
function fetchRankAndTellUtility(port, url) {
  initFetch({ "url": url, ranks: {}, refreshedCallback: function() {
    port.postMessage({type:"refresh", url: url});
  }});
}
function sendDataset(port, url, f) {
  SeoprofesionalDb.get_tl(url, f.id, function(res) {
    port.postMessage({
      type: "dataset",
      value: res,
      fetcher: f
    });
  });
}

</script>
</head>
<body onload="init()">
</body>
</html>

